package com.sxj.corejava.code15_反射;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Test06_解析注解 {

    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        Class c = Student.class;

        // 1.获取类上的所有注解
        Annotation[] annotations = c.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        System.out.println("***************************************");

        // 2.获取类上指定的注解
        Annotation annotation = c.getAnnotation(SomeAnnotation.class);
        System.out.println(annotation);
        annotation = c.getAnnotation(OtherAnnotation.class);
        System.out.println(annotation);
        System.out.println("***************************************");

        // 3.获取属性上所有注解
        Field idField = c.getDeclaredField("id");
        annotations = idField.getAnnotations();
        for (Annotation ann : annotations) {
            System.out.println(ann);
        }

        // 4.获取属性上指定注解
        annotation = idField.getAnnotation(SomeAnnotation.class);
        System.out.println(annotation);
        System.out.println("***************************************");

        // 5.获取方法上所有注解
        Method method = c.getDeclaredMethod("show");
        annotations = method.getAnnotations();
        for (Annotation ann : annotations) {
            System.out.println(ann);
        }

        // 6.获取方法上指定注解
        annotation = method.getAnnotation(OtherAnnotation.class);
        System.out.println(annotation);

        // 7.获取到指定注解中指定属性的值
        // 由于当前返回的注解对象都是Annotation类型的,无法直接调用子类方法
        // 先将对应的Annotation转换成子类对象
        if (annotation instanceof OtherAnnotation) {
            OtherAnnotation otherAnnotation = (OtherAnnotation) annotation;
            System.out.println(otherAnnotation.encoding());
            System.out.println(Arrays.toString(otherAnnotation.methods()));
        }

        annotation = method.getAnnotation(SomeAnnotation.class);
        if (annotation instanceof SomeAnnotation) {
            SomeAnnotation someAnnotation = (SomeAnnotation) annotation;
            System.out.println(someAnnotation.id());
            System.out.println(someAnnotation.name());
            System.out.println(someAnnotation.age());
            System.out.println(Arrays.toString(someAnnotation.value()));
        }

        // 8.判断调用者是否使用了指定注解
        // 在开发中,某些注解可能没有指定必须在元素上使用
        // 因此,如果直接解析,可能会报错
        annotation = idField.getAnnotation(OtherAnnotation.class);
        System.out.println(annotation);
        Field nameField = c.getDeclaredField("name");
        // 可以判断下该调用者是否使用了指定注解
        if (nameField.isAnnotationPresent(OtherAnnotation.class)) {
            annotation = nameField.getAnnotation(OtherAnnotation.class);
            System.out.println(annotation);
            OtherAnnotation otherAnnotation = (OtherAnnotation) annotation;
            System.out.println(otherAnnotation.encoding());
        } else {
            System.out.println("错误:name属性上没有使用OtherAnnotation的注解");
        }


    }

}
